package com.example.desksginktapp.views

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ImageFormat
import android.graphics.Matrix
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.YuvImage
import android.media.Image
import android.util.Log
import android.util.Size
import android.widget.Toast
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.ExperimentalGetImage
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.math.MathUtils
import com.example.baselibrary.utlis.Base64Utils
import com.example.baselibrary.utlis.FaceBoxView
import com.example.baselibrary.utlis.LogUtils
import com.example.baselibrary.utlis.ThreadManager
import com.example.desksginktapp.databinding.ActivityFaceDetectionBinding
import com.example.desksginktapp.viewmodels.FaceDetectionViewModel
import com.google.android.gms.tasks.OnCompleteListener
import com.google.android.gms.tasks.OnFailureListener
import com.google.android.gms.tasks.OnSuccessListener
import com.google.android.gms.tasks.Task
import com.google.common.util.concurrent.ListenableFuture
import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.face.Face
import com.google.mlkit.vision.face.FaceDetection
import com.google.mlkit.vision.face.FaceDetector
import com.google.mlkit.vision.face.FaceDetectorOptions
import com.zyf.baselibrary.base.BaseViewBindingActivity
import java.io.ByteArrayOutputStream
import java.lang.ref.WeakReference
import java.util.concurrent.ExecutionException
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.ThreadFactory
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.math.abs
import kotlin.math.exp
import kotlin.math.max
import kotlin.math.min

class FaceDetectionActivity :
    BaseViewBindingActivity<ActivityFaceDetectionBinding, FaceDetectionViewModel>() {
    private var previewWidth = 0
    private var previewHeight = 0
    private lateinit var mFaceDetectorOptions: FaceDetectorOptions
    private lateinit var cameraExecutor: ExecutorService
    private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
    private lateinit var cameraProvider: ProcessCameraProvider
    private val lensFacing = CameraSelector.LENS_FACING_BACK
    private lateinit var camera: Camera
    private var isFrontCamera = false
    private var displayRotation = 0
    private var analyzerWidth = 0
    private var analyzerHeight = 0
    private lateinit var faceDetector: FaceDetector
    private lateinit var mFaceBitmap: Bitmap
    private lateinit var mScaledBitmap: Bitmap
    private var lastCheckTicketTime: Long = 0
    private val CHECK_TICKET_INTERVAL: Long = 2000 // 1秒间隔
    private val isCheckIng = AtomicBoolean(false)
    private lateinit var faceOverlay: ConstraintLayout

    override fun provideViewModel(): FaceDetectionViewModel {
        return FaceDetectionViewModel()
    }

    override fun initViews() {
        super.initViews()
        faceOverlay = binding.faceOverlay
        binding.cameraPreview.post(object : Runnable {
            override fun run() {
                previewWidth = binding.cameraPreview.getWidth()
                previewHeight = binding.cameraPreview.getHeight()
            }
        })
    }

    @ExperimentalGetImage
    override fun onResume() {
        super.onResume()
        initFaceDetector()
        initCameraExecutor()
        initCamera()
    }

    /**
     * 初始化人脸检测器实例（线程安全方法）
     *
     *
     * 该方法用于懒加载方式创建并配置人脸检测器实例。如果检测器已存在则直接返回，
     * 否则创建新的检测器实例并配置为快速检测模式（不包含特征点和分类功能）。
     *
     * @throws IllegalStateException 当人脸检测器初始化失败时抛出
     */
    @Synchronized
    private fun initFaceDetector() {
        // 已存在实例时直接返回（避免重复初始化）
        if (::faceDetector.isInitialized) {
            return
        }

        // 配置检测器参数：快速模式，禁用特征点和分类检测以提升性能
        mFaceDetectorOptions = FaceDetectorOptions.Builder()
            .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST)
            .setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_NONE)
            .setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_NONE)
            .setMinFaceSize(0.3f)
            .build()

        // 创建检测器实例并检查初始化结果
        faceDetector = FaceDetection.getClient(mFaceDetectorOptions)
        checkNotNull(faceDetector) { "FaceDetector initialization failed" }
    }

    @Synchronized
    private fun initCameraExecutor() {
        /**
         * 初始化相机执行线程池。
         * 如果相机执行线程池已存在（不为null），则直接返回；
         * 否则创建一个单线程执行器作为相机执行线程池。
         */
        if (::cameraExecutor.isInitialized) {
            return
        }
        // 创建单线程执行器用于相机操作，并设置线程名称
        cameraExecutor = Executors.newSingleThreadExecutor(ThreadFactory { r: Runnable? ->
            val thread = Thread(r, "Camera-Executor")
            thread.setDaemon(false) // 明确设置为非守护线程
            thread
        })
    }

    @ExperimentalGetImage
    private fun initCamera() {
        val activityRef: WeakReference<FaceDetectionActivity?> =
            WeakReference<FaceDetectionActivity?>(this)
        binding.cameraPreview.post(object : Runnable {
            override fun run() {
                val activity: FaceDetectionActivity? =
                    activityRef.get()
                if (activity == null || activity.isFinishing()) {
                    return
                }

                cameraProviderFuture = ProcessCameraProvider.getInstance(activity)
                cameraProviderFuture.addListener(object : Runnable {
                    override fun run() {
                        val activity: FaceDetectionActivity? =
                            activityRef.get()
                        if (activity == null || activity.isFinishing()) {
                            return
                        }

                        try {
                            val provider: ProcessCameraProvider = cameraProviderFuture.get()
                            synchronized(this) {
                                cameraProvider = provider
                            }

                            if (!isCameraAvailable(lensFacing)) {
                                handleNoCameraAvailable()
                                return
                            }
                            startCamera()
                        } catch (e: ExecutionException) {
                            Log.e("摄像头", "Camera provider failed to initialize", e)
                            activity.runOnUiThread({
                                Toast.makeText(
                                    activity,
                                    "Camera initialization failed",
                                    Toast.LENGTH_SHORT
                                ).show()
                            })
                        } catch (e: InterruptedException) {
                            Log.e("摄像头", "Camera initialization interrupted", e)
                            Thread.currentThread().interrupt()
                        } catch (e: Exception) {
                            Log.e("摄像头", "Unexpected camera error", e)
                            activity.runOnUiThread({
                                Toast.makeText(
                                    activity,
                                    "Camera error occurred",
                                    Toast.LENGTH_SHORT
                                ).show()
                            })
                        }
                    }
                }, ContextCompat.getMainExecutor(activity))
            }
        })
    }

    @ExperimentalGetImage
    private fun handleNoCameraAvailable() {
        if (!isCameraAvailable(lensFacing)) {
            Toast.makeText(this, "No camera available", Toast.LENGTH_SHORT).show()
            return
        }
        startCamera()
    }

    private fun isCameraAvailable(lensFacing: Int): Boolean {
        // 验证lensFacing参数有效性
        if (lensFacing != CameraSelector.LENS_FACING_FRONT
            && lensFacing != CameraSelector.LENS_FACING_BACK
        ) {
            return false
        }

        try {
            val cameraSelector = CameraSelector.Builder()
                .requireLensFacing(lensFacing)
                .build()
            return cameraProvider != null && cameraProvider.hasCamera(cameraSelector)
        } catch (e: java.lang.Exception) {
            Log.e("CameraCheck", "Error checking camera availability", e)
            return false
        }
    }

    /**
     * 初始化并启动相机预览和图像分析功能。
     * 该方法会执行以下操作：
     * 1. 解绑所有已绑定的相机用例
     * 2. 配置预览视图的分辨率和表面提供者
     * 3. 设置图像分析器并指定分析策略
     * 4. 根据镜头方向选择相机
     * 5. 将预览和图像分析用例绑定到生命周期
     * 6. 记录当前显示旋转状态
     *
     *
     * 注意：如果过程中发生异常，会显示错误提示并记录日志
     */
    @ExperimentalGetImage
    private fun startCamera() {
        try {
            // 清理现有相机绑定
            if (::cameraProvider.isInitialized) {
                cameraProvider.unbindAll()
            }

            // 配置预览用例
            val preview = Preview.Builder()
                .setTargetResolution(Size(previewWidth, previewHeight))
                .build()
            preview.setSurfaceProvider(binding.cameraPreview.getSurfaceProvider())

            // 配置图像分析用例
            val imageAnalyzer = ImageAnalysis.Builder()
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                .setTargetResolution(Size(640, 480)) // 中等分辨率
                .build()
            imageAnalyzer.setAnalyzer(
                cameraExecutor,
                FaceAnalyzer(this)
            )

            // 根据镜头方向选择相机
            val cameraSelector = CameraSelector.Builder()
                .requireLensFacing(lensFacing)
                .build()

            // 绑定用例到生命周期
            camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalyzer)

            // 记录当前相机方向
            isFrontCamera = (lensFacing == CameraSelector.LENS_FACING_FRONT)

            // 获取并记录显示旋转状态
            displayRotation = binding.cameraPreview.getDisplay().getRotation()
            Log.d("startCamera", "Display rotation: " + displayRotation)
        } catch (exc: java.lang.Exception) {
            Log.e("startCamera", "Use case binding failed", exc)
            Toast.makeText(this, "Failed to start camera", Toast.LENGTH_SHORT).show()
        }
    }

    @ExperimentalGetImage
    private class FaceAnalyzer(
        private val activity: FaceDetectionActivity
    ) : ImageAnalysis.Analyzer {

        override fun analyze(imageProxy: ImageProxy) {
            val mediaImage = imageProxy.image ?: return imageProxy.close()

            synchronized(activity) {
                activity.analyzerWidth = imageProxy.width
                activity.analyzerHeight = imageProxy.height
            }

            val image = InputImage.fromMediaImage(
                mediaImage,
                imageProxy.getImageInfo().getRotationDegrees()
            )

            activity.faceDetector.process(image)
                .addOnSuccessListener(OnSuccessListener { faces: MutableList<Face>? ->
                    // 过滤正脸：姿态角度阈值（单位：度）
                    val frontalFaces: MutableList<Face?> = ArrayList<Face?>()
                    for (face in faces!!) {
                        // 关键过滤条件：左右偏转 | 上下俯仰 | 平面旋转 都要接近0度
                        if (abs(face.getHeadEulerAngleY().toDouble()) < 15 &&  // Y轴偏转（左右转头）
                            abs(face.getHeadEulerAngleX().toDouble()) < 20 &&  // X轴俯仰（抬头低头）
                            abs(face.getHeadEulerAngleZ().toDouble()) < 30
                        ) {  // Z轴旋转（头部倾斜）
                            frontalFaces.add(face)
                        }
                    }

                    if (!frontalFaces.isEmpty() && !faces.isEmpty()) {
                        val firstFace = faces.get(0)
                        try {
                            // 从 ImageProxy 获取人脸照片
                            activity.mFaceBitmap = extractFaceBitmap(
                                mediaImage,
                                imageProxy,
                                firstFace.getBoundingBox()
                            )
                            if (activity.mFaceBitmap != null) {
                                ThreadManager.getThreadPool().execute({
                                    // 在后台线程处理位图操作
                                    val matrix = Matrix()
                                    matrix.postRotate(-90f)
                                    if (activity.isFrontCamera) {
                                        matrix.postScale(-1f, 1f) // 前置摄像头需要镜像
                                    }

                                    val rotatedBitmap = Bitmap.createBitmap(
                                        activity.mFaceBitmap, 0, 0,
                                        activity.mFaceBitmap.getWidth() - 20,
                                        activity.mFaceBitmap.getHeight() - 20,
                                        matrix, true
                                    )
                                    activity.mFaceBitmap.recycle()

                                    activity.mScaledBitmap =
                                        Bitmap.createScaledBitmap(rotatedBitmap, 100, 100, true)
                                    rotatedBitmap.recycle()
                                    if (activity.mScaledBitmap != null) {
                                        val currentTime = System.currentTimeMillis()
//                                        runOnUiThread({
//                                            if (mIvFace != null) {
//                                                mIvFace.setVisibility(View.VISIBLE)
//                                                mIvFace.setImageBitmap(mScaledBitmap)
//                                            }
//                                        })
                                        // 使用 compareAndSet 避免并发请求
                                        if ((currentTime - activity.lastCheckTicketTime) > activity.CHECK_TICKET_INTERVAL && activity.isCheckIng.compareAndSet(
                                                false,
                                                true
                                            )
                                        ) {
                                            // 重置时间戳
                                            activity.lastCheckTicketTime = currentTime
                                            val base64Image: String? =
                                                Base64Utils.bitmap2Base64(activity.mScaledBitmap)
                                            // 执行网络请求
                                            LogUtils.logEvent("网络请求111开始-isCheckIng222")
//                                            checkTicket(base64Image)
                                        }
                                    }
                                })
                            }
                        } catch (e: java.lang.Exception) {
                            Log.e("FaceAnalyzer", "Failed to extract face bitmap", e)
//                            runOnUiThread({
//                                mIvFace.setVisibility(View.VISIBLE)
//                                mIvFace.setImageResource(R.drawable.ic_launcher_background)
//                            })
                        }
                    }
                    // 更新UI
                    drawFaceBoxes(faces, imageProxy)
                })
                .addOnFailureListener(OnFailureListener { e: java.lang.Exception? ->
                    Log.e(
                        "FaceAnalyzer",
                        "Face detection failed",
                        e
                    )
                })
                .addOnCompleteListener(OnCompleteListener { task: Task<MutableList<Face>?>? -> imageProxy.close() })
        }

        fun drawFaceBoxes(faces: MutableList<Face>, imageProxy: ImageProxy?) {
            // 每次调用都先清除所有框和人脸信息
            activity.faceOverlay.removeAllViews()
            // 如果没有检测到人脸，直接返回
            if (faces.isEmpty()) {
                return
            }
            LogUtils.logEvent("检测人脸开始时间--有人脸了，去画人脸框")
            for (index in faces.indices) {
                val face = faces.get(index)
                val bounds = face.getBoundingBox()

                val transformedRect = calculateTransformedRect(
                    RectF(
                        bounds.left.toFloat(), bounds.top.toFloat(),
                        bounds.right.toFloat(), bounds.bottom.toFloat()
                    ),
                    0,
                    activity.analyzerWidth,
                    activity.analyzerHeight
                )

                // 确保矩形在视图范围内
                val clampedRect = RectF(
                    MathUtils.clamp(transformedRect.left, 0f, activity.previewWidth.toFloat()),
                    MathUtils.clamp(transformedRect.top, 0f, activity.previewHeight.toFloat()),
                    MathUtils.clamp(transformedRect.right, 0f, activity.previewWidth.toFloat()),
                    MathUtils.clamp(transformedRect.bottom, 0f, activity.previewHeight.toFloat())
                )

                if (clampedRect.width() <= 0 || clampedRect.height() <= 0) {
                    Log.w(
                        "TAG",
                        "Invalid face box #" + index + ": " + clampedRect.width() + "x" + clampedRect.height()
                    )
                    continue
                }

                val boxView: FaceBoxView = FaceBoxView(activity)
                val layoutParams = ConstraintLayout.LayoutParams(
                    clampedRect.width().toInt(),
                    clampedRect.height().toInt()
                )
                layoutParams.leftToLeft = ConstraintLayout.LayoutParams.PARENT_ID
                layoutParams.topToTop = ConstraintLayout.LayoutParams.PARENT_ID
                layoutParams.setMarginStart(clampedRect.left.toInt())
                layoutParams.topMargin = clampedRect.top.toInt()
                boxView.setLayoutParams(layoutParams)
                boxView.setFaceBounds(RectF(0f, 0f, clampedRect.width(), clampedRect.height()))

                activity.faceOverlay.addView(boxView)
            }
        }


        fun sigmoid(x: Float): Float {
            return 1f / (1f + exp((-10f * (x - 0.5f)).toDouble()).toFloat())
        }

fun calculateTransformedRect(
    rectangle: RectF,
    rotationDegrees: Int,
    imageWidth: Int,
    imageHeight: Int
): RectF {
    // 1. Normalize coordinates to the range [0,1]
    val normalizedLeft = rectangle.left / imageWidth
    val normalizedTop = rectangle.top / imageHeight
    val normalizedRight = rectangle.right / imageWidth
    val normalizedBottom = rectangle.bottom / imageHeight

    var transformedLeft = normalizedLeft
    var transformedTop = normalizedTop
    var transformedRight = normalizedRight
    var transformedBottom = normalizedBottom

    // 2. Adjust coordinates based on rotation angle
    when (rotationDegrees) {
        90 -> {
            // Rotate 90 degrees clockwise
            transformedLeft = normalizedTop
            transformedTop = 1 - normalizedRight
            transformedRight = normalizedBottom
            transformedBottom = 1 - normalizedLeft
        }

        180 -> {
            // Rotate 180 degrees
            transformedLeft = 1 - normalizedRight
            transformedTop = 1 - normalizedBottom
            transformedRight = 1 - normalizedLeft
            transformedBottom = 1 - normalizedTop
        }

        270 -> {
            // Rotate 270 degrees clockwise (90 degrees counterclockwise)
            transformedLeft = 1 - normalizedBottom
            transformedTop = normalizedLeft
            transformedRight = 1 - normalizedTop
            transformedBottom = normalizedRight
        }
    }

    // 3. Handle front camera mirror (horizontal flip)
    if (activity.isFrontCamera) {
        transformedLeft = 1 - transformedLeft
        transformedRight = 1 - transformedRight
        // Swap left and right boundaries
        val temp = transformedLeft
        transformedLeft = transformedRight
        transformedRight = temp
    }

    // 4. Position calibration: adjust position in normalized coordinate system
    // Calculate the center position of the face in the image
    val centerX = (transformedLeft + transformedRight) / 2
    val centerY = (transformedTop + transformedBottom) / 2

    // 调整后的参数 - 减小垂直偏移量，使人脸框向上移动(减少之前的向下偏移)
    val verticalBaseShift = 0.2f // 减小基础垂直偏移 (从0.4f调整为0.2f)
    val verticalDynamicShift = 0.1f * (1f - sigmoid(centerY)) // 减小动态垂直偏移 (从0.2f调整为0.1f)

    // 调整水平偏移量，使人脸框向左移动一点点
    val horizontalBaseShift = 0.15f // 减小基础水平偏移 (从0.3f调整为0.15f)
    val horizontalDynamicShift = 0.1f * sigmoid(centerX) // 减小动态水平偏移 (从0.2f调整为0.1f)

    val verticalShiftRatio = verticalBaseShift + verticalDynamicShift
    val horizontalShiftRatio = horizontalBaseShift + horizontalDynamicShift

    // Apply offsets - 改为加法操作，使人脸框向下移动
    val width = transformedRight - transformedLeft
    val height = transformedBottom - transformedTop

    // 要向下移动框，应该增加top和bottom的值
    transformedTop += height * verticalShiftRatio
    transformedBottom += height * verticalShiftRatio
    transformedLeft -= width * horizontalShiftRatio
    transformedRight -= width * horizontalShiftRatio

    // 5. Convert to preview view coordinates
    val previewLeft: Float = transformedLeft * activity.previewWidth
    val previewTop: Float = transformedTop * activity.previewHeight
    val previewRight: Float = transformedRight * activity.previewWidth
    val previewBottom: Float = transformedBottom * activity.previewHeight

    // 6. Create a compact minimum enclosing square
    val originalRectangle = RectF(previewLeft, previewTop, previewRight, previewBottom)

    // Calculate center point
    val previewCenterX = originalRectangle.centerX()
    val previewCenterY = originalRectangle.centerY()

    // Calculate minimum side length (to fit the square around the face)
    val minSide = min(
        originalRectangle.width().toDouble(),
        originalRectangle.height().toDouble()
    ).toFloat()
    val halfSide = minSide / 2

    // 7. Calculate square boundaries
    var squareLeft = previewCenterX - halfSide
    var squareTop = previewCenterY - halfSide
    var squareRight = previewCenterX + halfSide
    var squareBottom = previewCenterY + halfSide

    // 8. Boundary protection: ensure the square is within the screen
    // If the square exceeds the left side, move right
    if (squareLeft < 0) {
        val offset = -squareLeft
        squareLeft += offset
        squareRight += offset
    }

    // If the square exceeds the top, move down
    if (squareTop < 0) {
        val offset = -squareTop
        squareTop += offset
        squareBottom += offset
    }

    // If the square exceeds the right side, move left
    if (squareRight > activity.previewWidth) {
        val offset: Float = squareRight - activity.previewWidth
        squareRight -= offset
        squareLeft -= offset
    }

    // If the square exceeds the bottom, move up
    if (squareBottom > activity.previewHeight) {
        val offset: Float = squareBottom - activity.previewHeight
        squareBottom -= offset
        squareTop -= offset
    }

    // 9. Return the adjusted square
    return RectF(squareLeft, squareTop, squareRight, squareBottom)
}


        private fun extractFaceBitmap(
            mediaImage: Image,
            imageProxy: ImageProxy,
            faceBounds: Rect
        ): Bitmap {
            try {
                // 1. Convert Image to Bitmap
                val yBuffer = mediaImage.getPlanes()[0].getBuffer() // Y
                val uBuffer = mediaImage.getPlanes()[1].getBuffer() // U
                val vBuffer = mediaImage.getPlanes()[2].getBuffer() // V

                val ySize = yBuffer.remaining()
                val uSize = uBuffer.remaining()
                val vSize = vBuffer.remaining()

                val nv21 = ByteArray(ySize + uSize + vSize)
                yBuffer.get(nv21, 0, ySize)
                vBuffer.get(nv21, ySize, vSize)
                uBuffer.get(nv21, ySize + vSize, uSize)

                val yuvImage = YuvImage(
                    nv21,
                    ImageFormat.NV21,
                    mediaImage.getWidth(),
                    mediaImage.getHeight(),
                    null
                )

                val outputStream = ByteArrayOutputStream()
                yuvImage.compressToJpeg(
                    Rect(0, 0, mediaImage.getWidth(), mediaImage.getHeight()),
                    90,
                    outputStream
                )

                val fullBitmap = BitmapFactory.decodeByteArray(
                    outputStream.toByteArray(),
                    0,
                    outputStream.size()
                )
                checkNotNull(fullBitmap) { "Failed to decode bitmap" }

                // 2. Adjust and validate face area
                val rotatedFaceRect: RectF = adjustFaceRectForRotation(
                    faceBounds,
                    imageProxy.getImageInfo().getRotationDegrees(),
                    mediaImage.getWidth(),
                    mediaImage.getHeight()
                )

                // Ensure the rectangle is within image bounds
                rotatedFaceRect.left = max(rotatedFaceRect.left.toDouble(), 0.0).toFloat()
                rotatedFaceRect.top = max(rotatedFaceRect.top.toDouble(), 0.0).toFloat()
                rotatedFaceRect.right = min(
                    rotatedFaceRect.right.toDouble(),
                    fullBitmap.getWidth().toDouble()
                ).toFloat()
                rotatedFaceRect.bottom = min(
                    rotatedFaceRect.bottom.toDouble(),
                    fullBitmap.getHeight().toDouble()
                ).toFloat()

                // Ensure width and height are positive
                require(!(rotatedFaceRect.width() <= 0 || rotatedFaceRect.height() <= 0)) { "Invalid face bounds after rotation" }

                val faceBitmap = Bitmap.createBitmap(
                    fullBitmap,
                    rotatedFaceRect.left.toInt(),
                    rotatedFaceRect.top.toInt(),
                    rotatedFaceRect.width().toInt(),
                    rotatedFaceRect.height().toInt()
                )
                fullBitmap.recycle() // 手动回收原Bitmap
                return faceBitmap
            } catch (e: java.lang.Exception) {
                Log.e("TAG", "Failed to extract face bitmap", e)
                // Return an empty Bitmap or default image
                val errorBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
                val canvas = Canvas(errorBitmap)
                canvas.drawColor(Color.RED) // 标记错误为红色
                return errorBitmap
            }
        }

        private fun adjustFaceRectForRotation(
            rect: Rect,
            rotationDegrees: Int,
            imageWidth: Int,
            imageHeight: Int
        ): RectF {
            when (rotationDegrees) {
                90 -> return normalize(
                    RectF(
                        max(0.0, min(rect.top.toDouble(), imageHeight.toDouble())).toFloat(),
                        max(
                            0.0,
                            min((imageHeight - rect.right).toDouble(), imageWidth.toDouble())
                        ).toFloat(),
                        max(0.0, min(rect.bottom.toDouble(), imageHeight.toDouble())).toFloat(),
                        max(
                            0.0,
                            min((imageHeight - rect.left).toDouble(), imageWidth.toDouble())
                        ).toFloat()
                    )
                )

                180 -> return normalize(
                    RectF(
                        max(
                            0.0,
                            min((imageWidth - rect.right).toDouble(), imageWidth.toDouble())
                        ).toFloat(),
                        max(
                            0.0,
                            min((imageHeight - rect.bottom).toDouble(), imageHeight.toDouble())
                        ).toFloat(),
                        max(
                            0.0,
                            min((imageWidth - rect.left).toDouble(), imageWidth.toDouble())
                        ).toFloat(),
                        max(
                            0.0,
                            min((imageHeight - rect.top).toDouble(), imageHeight.toDouble())
                        ).toFloat()
                    )
                )

                270 -> return normalize(
                    RectF(
                        max(
                            0.0,
                            min((imageWidth - rect.bottom).toDouble(), imageWidth.toDouble())
                        ).toFloat(),
                        max(0.0, min(rect.left.toDouble(), imageHeight.toDouble())).toFloat(),
                        max(
                            0.0,
                            min((imageWidth - rect.top).toDouble(), imageWidth.toDouble())
                        ).toFloat(),
                        max(0.0, min(rect.right.toDouble(), imageHeight.toDouble())).toFloat()
                    )
                )

                else -> return normalize(
                    RectF(
                        max(0.0, min(rect.left.toDouble(), imageWidth.toDouble())).toFloat(),
                        max(0.0, min(rect.top.toDouble(), imageHeight.toDouble())).toFloat(),
                        max(0.0, min(rect.right.toDouble(), imageWidth.toDouble())).toFloat(),
                        max(0.0, min(rect.bottom.toDouble(), imageHeight.toDouble())).toFloat()
                    )
                )
            }
        }

        private fun normalize(rectF: RectF): RectF {
            if (rectF.left > rectF.right) {
                val temp = rectF.left
                rectF.left = rectF.right
                rectF.right = temp
            }
            if (rectF.top > rectF.bottom) {
                val temp = rectF.top
                rectF.top = rectF.bottom
                rectF.bottom = temp
            }
            return rectF
        }
    }

}